/**
 * @class   wosh::communication::ShellCommand
 * @brief   The class holds a shell command and its arguments (as string).
 *
 *
 *
 * wosh::MethodArguments
 *
 *
 *
 * @see     wosh::SessionProtocol
 ****************************************************************************
 * @version 0.8.013 $Id: ShellCommand.h 2848 2010-08-06 15:03:50Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Communication_ShellCommand_H__
 #define __WOSH_Communication_ShellCommand_H__

 #include <woshDefs.h>
 #include <core/Variant.h>
 #include <string>
 #include <vector>


namespace wosh {
 class Request;
 class Table;
 class List;

 namespace communication {

struct ShellCommandArg {
	Variant argument;
	std::string field;

	ShellCommandArg& operator=( const ShellCommandArg& m ) {
		if ( this == &m ) return *this; // same object?
		field = m.field;
		argument = m.argument;
		return *this;
	 }

	bool operator==( const ShellCommandArg& other ) const {
		if ( field != other.field )
			return false;
		if ( argument != other.argument )
			return false;
		return true;
	 }

};


class ShellCommand
 {
	public:
		/**
		 * @brief  Empty constructor.
		 */
		ShellCommand() : hasFields(false) { }

		ShellCommand( const std::string& dataline ) : hasFields(false) {
			fromString(dataline);
		 }
		/**
		 * @brief  Copy constructor.
		 * @param m [in] the source object to be copied
		 */
		ShellCommand( const ShellCommand& m )
			: command(m.command), arguments(m.arguments), hasFields(m.hasFields) { }
		/**
		 * @brief  Empty destructor.
		 */
		virtual ~ShellCommand() { }

	public:
		void clear();

		virtual bool fromString( const std::string& dataline );

//		void appendArgumentsTo( wosh::List* dl );

		Request* toRequest() const;

		Table* toArgumentTable() const;
		List* toArgumentList() const;

		std::string toString( bool include_command = true ) const;

/** @name Getters
 * @{
 ******************************************************************************/
 	public:
		const std::string& getMainCommand() const				{ return this->command; }

		inline int getArgCount() const 							{ return this->arguments.size(); }

		const Variant& getArgument( int index ) const;
		const Variant& getArgument( const std::string& field ) const;

//		const std::string& getArg( unsigned int index ) const;

		const std::vector<ShellCommandArg>& getArguments() const	{ return this->arguments; }
		std::vector<ShellCommandArg>& getArguments()				{ return this->arguments; }

		bool hasArgumentFields() const								{ return this->hasFields; }
//@}
/** name Setters
 * @{
 ******************************************************************************/
 	public:
		void setMainCommand( const std::string& value ) 			{ this->command = value; }
//@}

		ShellCommand& operator=( const ShellCommand& m );

		bool operator==( const ShellCommand& other ) const;

	protected:
		std::string command;				///< the main command
		std::vector<ShellCommandArg> arguments;	///< list of arguments as (trimmed) strings
		bool hasFields;

		void parseArgs( const std::string& args, std::string& current_field );

}; // class def

 }; // namespace communication
}; // namespace wosh

#endif //__WOSH_Communication_ShellCommand_H__
